iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 2
0

當我們想要在TextView上顯示省略號 會使用屬性 android:ellipsize,
同時也要設置android:singleline = "true"
省略號才會生效

如果我想要顯示多行,又想要省略號時
只能透過自寫一個函式設定行數,以及顯示的省略文字。

/**
 *  mtextView : 要顯示的Textview
 *  mMaxLine  : 要限制的行數
 *  mShowString : 要顯示的內容
 **/

        fun limitTextviewMaxLine(mtextView : TextView, mMaxLine : Int, mShowString : String){
            var mViewTreeObserver= mtextView.viewTreeObserver
            var mGlobalLayoutListener= object : ViewTreeObserver.OnGlobalLayoutListener{
                @RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
                override fun onGlobalLayout() {
                    mtextView.setText(mShowString)
                    when{
                        mtextView.lineCount > mMaxLine ->{
                            mtextView.viewTreeObserver.removeOnGlobalLayoutListener(this)
                            var endPosition=mtextView.layout.getLineEnd(mMaxLine-1)
                            var limitText=mShowString.subSequence(0,endPosition-3).toString()+"..."
                            mtextView.setText(limitText)
                        }
                        else ->{
                            mtextView.viewTreeObserver.removeOnGlobalLayoutListener(this)
                        }
                    }
                }
            }
            mViewTreeObserver.addOnGlobalLayoutListener(mGlobalLayoutListener)
        }

以下來解釋程式碼
var mViewTreeObserver= mtextView.viewTreeObserver
我們先宣告一個ViewTreeObserver當作觀察者,當這個元件的佈局改變跟繪製事件觸發時,
都可以藉由這個觀察者進行監聽處理。

var mGlobalLayoutListener= object : ViewTreeObserver.OnGlobalLayoutListener
之後我們在這裡使用ViewTreeObserver.OnGlobalLayoutListener來監聽布局事件,
當一個元件的layout的要求生效時,會觸發onGlobalLayout事件。

mtextView.setText(mShowString)
為什麼要寫這一行?
我們的要求是限制行數,並用省略字串代替。
所以先把要顯示的內容傳給TextView,讓接下來的判斷可以去就實際的TextView的值去操作。
為什麼不直接處理字串?
因為我們不知道這個字串在進入TextView後,會被分成幾行。
除非我們先把整個布局的寬度跟字串長度算好,然後確認會分成幾行進行處理,
不然還是交給元件去處理吧。

mtextView.lineCount > mMaxLine
這邊直接就可以由元件計算行數,是不是很方便?

這邊分為兩個部分判斷
大於mMaxLine跟小於等於mMaxLine

當大於mMaxLine時
var endPosition=mtextView.layout.getLineEnd(mMaxLine-1)
var limitText=mShowString.subSequence(0,endPosition-3).toString()+"..."

取得最大行數該行的最後一個字元位置後,往前移3個字元並截取內容,後面加上"..."取代後面的內容。

mtextView.viewTreeObserver.removeOnGlobalLayoutListener(this)
記得每次判斷後移除OnGlobalLayoutListener,不然影響效能

我們在使用函式時,使用limitTextviewMaxLine(要使用此格式的TextView,要限制的行數,輸入內容)
就可以達成我們所要的效果了。


上一篇
TextView Html顯示與超連結的用法
下一篇
Android Back倒退鍵 事件攔截
系列文
跟Kotlin一起來聊Android元件 或許還有應用,或許還有一些資訊雜談30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言